const fs = require('fs')
const bencode = require('bencode')
const crypto = require('crypto')
const bigintBuffer = require('bigint-buffer')

module.exports = {
  readTorrent (path) {
    const torrent = bencode.decode(fs.readFileSync(path))

    if (torrent.announce) {
      console.log(`announce: ${torrent.announce.toString('utf8')}`)
    }
    if (torrent['announce-list']) {
      torrent['announce-list'].forEach(element => {
        element.forEach(announce => {
          console.log(`announce: ${announce.toString('utf8')}`)
        })
      })
    }

    return torrent
  },
  infoHash (torrent) {
    const info = bencode.encode(torrent.info)
    return crypto.createHash('sha1').update(info).digest()
  },
  size (torrent) {
    const size = torrent.info.files ?
      torrent.info.files.map(file => file.length).reduce((a, b) => a + b) :
      torrent.info.length

    return bigintBuffer.toBufferBE(size, 8)
  },

  // Break pieces into blocks.
  BLOCK_LEN: Math.pow(2, 14),
  pieceLen (torrent, pieceIndex) {
    const totalLength = Number(bigintBuffer.toBigIntBE(this.size(torrent)))
    const pieceLength = torrent.info['piece length']

    const lastPieceIndex = Math.floor(totalLength / pieceLength)
    const lastPieceLength = totalLength % pieceLength

    return lastPieceIndex === pieceIndex ? lastPieceLength : pieceLength
  },
  blockNum (torrent, pieceIndex) {
    const pieceLength = this.pieceLen(torrent, pieceIndex)
    return Math.ceil(pieceLength / this.BLOCK_LEN)
  },
  blockLen (torrent, pieceIndex, blockIndex) {
    const pieceLength = this.pieceLen(torrent, pieceIndex)

    const lastBlockIndex = Math.floor(pieceLength / this.BLOCK_LEN)
    const lastBlockLength = pieceLength % this.BLOCK_LEN

    return blockIndex === lastBlockIndex ? lastBlockLength : this.BLOCK_LEN
  }
}